package EA;
import EA.Framework;
import RKUjava.lang.*;
import java.util.Vector;

/** Abstract NumericalTreeGenome class for any EA with tree representation. 
    Trees are represented with arrows in both directions, i.e. each
    node contains pointers to both sons and father. If all the length of
    the sons-array is zero then the NumericalTreeGenome is a leaf in the whole tree. 
    The NumericalTreeGenome is the root of the tree if the father is null. 
*/
public class NumericalTreeGenome extends TreeGenome
{
  public NumericalTreeGenome(Framework frame)
    {
      super(frame);
    }

  /** Create a new NumericalTreeGenome. 
      This constructor can generate a random tree with a given depth.
      @param frame A TreeFramework.
      @param depth The depth of the random tree. If -2 is passed the method
      will generate a tree with no maximal depth. If -1 is passed the maximal
      depth will automatically be taken from the TreeFramework passed in frame.
  */
  public NumericalTreeGenome(Framework frame, int depth)
    {
      super(frame, depth);
    }

  /** Create a new NumericalTreeGenome. 
      This constructor can generate a random tree with a given depth.
      @param frame A TreeFramework.
      @param depth The depth of the random tree. If -2 is passed the method
      will generate a tree with no maximal depth. If -1 is passed the maximal
      depth will automatically be taken from the TreeFramework passed in frame.
      @param container A possible container for this NumericalTreeGenome, e.g. 
      a subclass of Individual, TreeFramework or something else. 
      It is used by the NumericalTreeGenomeContents to extract information from the
      container.
  */
  public NumericalTreeGenome(Framework frame, int depth, Object container)
    {
      super(frame, depth, container);
    }

  /** Evaluate the tree. Don't override this method unless you know what you
      are doing.
  */
  public double evaluateNumerical()
    {
      if (sons.length == 0) {
	  return ((NumTreeGenomeContents)contents).evaluateNumerical();
	}
      else {
	double tempres[] = new double[sons.length];
	// Evaluate each of the sons.
	for(int i=0;i<sons.length;i++) {
	  tempres[i] = ((NumericalTreeGenome)sons[i]).evaluateNumerical();
	}
	// Return the values combined according to the operator in the contents
	return ((NumTreeGenomeContents)contents).evaluateNumerical(tempres);
      }
    }

  /** Return the NumericalTreeGenomeContents as a TreeGenomeFastEvaluation-tree.
      Can be used for fast evaluation of the tree.
  */
  public TreeGenomeFastEval getAsFastEvaluation()
    {
      TreeGenomeFastEval res;

      res = contents.getAsFastEvaluation();
      for (int i=0;i<res.sons.length;i++) {
	res.sons[i] = sons[i].getAsFastEvaluation();
      }
      return res;
    }

}




